<template>
  <span>{{ displayText }}</span>
</template>

<script>
export default {
  name: 'TypedComponent',
  props: {
    text: {
      type: String,
      required: true
    },
    speed: {
      type: Number,
      default: 30 // 默认速度30，但会被固定使用
    },
    shouldStop: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      displayText: '',
      currentIndex: 0,
      worker: null,
      workerId: null,
      backgroundMode: false,
      isComplete: false,
      timer: null
    };
  },
  watch: {
    text: {
      immediate: true,
      handler(newText) {
        // 每次文本变化时重新打字
        this.isComplete = false;
        this.startTyping(newText);
      }
    },
    shouldStop(newVal) {
      if (newVal) {
        // 立即停止打字效果
        this.terminateWorker();
        this.clearTypingTimer();
        // 直接显示完整文本
        this.displayText = this.text;
        this.isComplete = true;
        this.$emit("typing-complete");
      }
    }
  },
  mounted() {
    // 添加页面可见性监听
    document.addEventListener('visibilitychange', this.handleVisibilityChange);
    
    // 创建Worker
    this.createWorker();
  },
  beforeDestroy() {
    // 清理资源
    this.clearTypingTimer();
    this.terminateWorker();
    document.removeEventListener('visibilitychange', this.handleVisibilityChange);
  },
  methods: {
    // 创建Web Worker
    createWorker() {
      try {
        // 检查浏览器是否支持Worker
        if (typeof Worker !== 'undefined') {
          // 终止已存在的Worker
          this.terminateWorker();
          
          // 创建Worker
          const workerUrl = `${window.location.origin}/workers/typingWorker.js`;
          
          // 检查Worker文件是否存在
          fetch(workerUrl, { method: 'HEAD' })
            .then(response => {
              if (!response.ok) throw new Error('Worker文件不存在');
              
              this.worker = new Worker(workerUrl);
              
              // 设置消息处理函数
              this.worker.onmessage = (e) => {
                const { id, text, isDone } = e.data;
                
                // 心跳消息忽略
                if (e.data.heartbeat) return;
                
                // 确认这是当前任务的响应
                if (id === this.workerId) {
                  this.displayText = text;
                  
                  if (isDone) {
                    this.isComplete = true;
                    this.$emit("typing-complete");
                  }
                }
              };
              
              // 添加错误处理
              this.worker.onerror = (error) => {
                console.error('Worker运行错误:', error);
                // 出错时退回到备用方式
                this.worker = null;
                if (!this.isComplete && this.text) {
                  this.useTimestampTyping();
                }
              };
              
              console.log('打字Worker创建成功');
              
              // 如果有待处理文本，立即开始
              if (this.text && !this.isComplete) {
                this.startTyping(this.text);
              }
            })
            .catch(error => {
              console.error('Worker文件访问失败:', error);
              this.worker = null;
              // 退回到备用方式
              if (this.text && !this.isComplete) {
                this.useTimestampTyping();
              }
            });
        } else {
          console.warn('当前浏览器不支持Web Worker，将使用备用方式');
          this.worker = null;
        }
      } catch (error) {
        console.error('创建Web Worker失败:', error);
        this.worker = null;
      }
    },
    
    // 终止Worker
    terminateWorker() {
      if (this.worker) {
        this.worker.terminate();
        this.worker = null;
        this.workerId = null;
      }
    },
    
    // 处理页面可见性变化
    handleVisibilityChange() {
      this.backgroundMode = document.visibilityState === 'hidden';
      
      if (this.backgroundMode) {
        // 页面不可见时，直接显示完整文本
        this.terminateWorker();
        this.clearTypingTimer();
        this.displayText = this.text;
        this.isComplete = true;
        this.$emit("typing-complete");
      } else {
        // 页面重新可见时，如果文本还没完成打字，则重新开始
        if (!this.isComplete && this.text) {
          this.startTyping(this.text);
        }
      }
      
      console.log(`页面可见性变化: ${this.backgroundMode ? '不可见' : '可见'}`);
    },
    
    // 基于时间戳的备用打字方法 - 在Worker不可用时使用
    useTimestampTyping() {
      const text = this.text;
      const startTime = Date.now();
      const charCount = text.length - this.currentIndex;
      const fixedSpeed = 30; // 固定速度30ms
      const totalDuration = charCount * fixedSpeed;
      const endTime = startTime + totalDuration;
      
      // 清除现有定时器
      this.clearTypingTimer();
      
      const updateText = () => {
        const now = Date.now();
        const progress = Math.min(1, (now - startTime) / totalDuration);
        const charPosition = Math.floor(this.currentIndex + progress * charCount);
        
        if (charPosition > this.currentIndex) {
          this.displayText = text.substring(0, charPosition);
          this.currentIndex = charPosition;
        }
        
        if (now < endTime) {
          // 使用requestAnimationFrame持续更新
          this.timer = requestAnimationFrame(updateText);
        } else {
          // 完成打字
          this.displayText = text;
          this.currentIndex = text.length;
          this.isComplete = true;
          this.$emit("typing-complete");
        }
      };
      
      // 启动动画
      this.timer = requestAnimationFrame(updateText);
    },
    
    // 清理定时器
    clearTypingTimer() {
      if (this.timer) {
        cancelAnimationFrame(this.timer);
        this.timer = null;
      }
    },
    
    // 开始打字
    startTyping(text) {
      // 如果文本为空，立即完成
      if (!text || text.length === 0) {
        this.displayText = "";
        this.isComplete = true;
        this.$emit("typing-complete");
        return;
      }
      
      // 重置状态
      this.displayText = "";
      this.currentIndex = 0;
      this.clearTypingTimer();
      this.isComplete = false;
      
      // 优先使用Web Worker
      if (this.worker) {
        // 生成唯一任务ID
        this.workerId = Date.now().toString();
        
        // 发送打字任务给Worker
        this.worker.postMessage({
          text: text,
          speed: 30, // 固定速度为30
          id: this.workerId
        });
        
        console.log('使用Worker模式打字，固定速度:30ms');
        return;
      }
      
      // 如果Worker不可用，使用时间戳驱动的备用方法
      this.useTimestampTyping();
    }
  }
};
</script>